package com.dupf.product.web.controller.product;

import com.dupf.common.base.BaseController;
import com.dupf.common.util.CommonThreadPool;
import com.dupf.common.util.ItvJsonUtil;
import com.dupf.common.util.JmsUtil;
import com.dupf.common.util.PoiUtils;
import com.dupf.product.common.constant.ProductResult;
import com.dupf.product.common.constant.ProductResultConstant;
import com.dupf.product.dao.model.*;
import com.dupf.product.dao.smodel.ProductCollectParamDTO;
import com.dupf.product.dao.smodel.ProductExportParamDTO;
import com.dupf.product.dao.smodel.ProductExportResultDTO;
import com.dupf.product.rpc.api.*;
import com.dupf.upms.common.constant.UpmsResult;
import com.dupf.upms.common.constant.UpmsResultConstant;
import com.dupf.upms.rpc.api.UpmsApiService;
import com.google.common.base.Splitter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 产品controller
 * Created by dupf on 2018/3/20.
 */
@RestController
@Api(value = "产品管理", description = "产品管理")
@RequestMapping("/product")
public class ProductInfoController extends BaseController {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProductInfoController.class);
    private static final String AMAZON_TEMPLATE_BASE_PATH = "/data/work/finalTemp/";

    @Autowired
    private ProductInfoService productInfoService;

    @Autowired
    private ProductDetailService productDetailService;

    @Autowired
    private ProductCollectService productCollectService;

    @Autowired
    private ProductCollectRecordService productCollectRecordService;

    @Autowired
    private ProductCategoryService productCategoryService;

    @Autowired
    private UpmsApiService upmsApiService;

    @Autowired
    private JmsTemplate jmsQueueTemplate;

    @Autowired
    private ActiveMQQueue defaultQueueDestination;

    @Autowired
    private ProductVariantService productVariantService;

    @ApiOperation(value = "产品列表")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ResponseBody
    public Object list(
            @RequestParam(required = true, defaultValue = "1,2,3,4", value = "status") String status,
            @RequestParam(required = false, defaultValue = "", value = "sourceDomain") String sourceDomain,
            @RequestParam(required = false, defaultValue = "", value = "categoryId") String categoryId,
            @RequestParam(required = false, defaultValue = "", value = "title") String title,
            @RequestParam(required = false, defaultValue = "", value = "sku") String sku,
            @RequestParam(required = false, defaultValue = "", value = "productNo") String productNo,
            @RequestParam(required = false, defaultValue = "", value = "userId") Integer empUserId,
            @RequestParam(required = false, defaultValue = "", value = "startTime") Long startTime,
            @RequestParam(required = false, defaultValue = "", value = "endTime") Long endTime,
            @RequestParam(required = false, defaultValue = "0", value = "offset") int offset,
            @RequestParam(required = false, defaultValue = "10", value = "limit") int limit,
            HttpServletRequest request
    ) {
        Integer userId = (Integer) request.getAttribute("currentUserId");
        Integer orgId = (Integer) request.getAttribute("currentOrgId");
        ProductInfoExample productInfoExample = new ProductInfoExample();
        ProductInfoExample.Criteria criteria = productInfoExample.createCriteria();

        if (empUserId != null) {
            criteria.andCollectUserIdEqualTo(empUserId);
        } else {
            criteria.andCollectUserIdEqualTo(userId);
        }

        criteria.andOrgIdEqualTo(orgId);

        // 状态
        criteria.andStatusIn(Splitter.on(",").splitToList(status).stream().map(Byte::valueOf).collect(Collectors.toList()));

        // 域名
        if (StringUtils.isNotBlank(sourceDomain)) {
            criteria.andSourceDomainEqualTo(sourceDomain);
        }

        // 标题
        if (StringUtils.isNotBlank(title)) {
            criteria.andTitleLike("%" + title + "%");
        }

        // sku
        if (StringUtils.isNotBlank(sku)) {
            criteria.andSkuEqualTo(sku);
        }

        // empUserId
//        if (empUserId != null) {
//            criteria.andCollectUserIdEqualTo(empUserId);
//        }

        // productNo
        if (StringUtils.isNotBlank(productNo)) {
            criteria.andProductNoEqualTo(productNo);
        }

        // 开始时间和结束时间
        if (startTime != null && endTime != null) {
            criteria.andReleaseTimeBetween(startTime, endTime);
        } else if (startTime != null) {
            criteria.andReleaseTimeGreaterThanOrEqualTo(startTime);
        } else if (endTime != null) {
            criteria.andReleaseTimeLessThanOrEqualTo(endTime);
        }

        // 分类
        if (StringUtils.isNotBlank(categoryId)) {
            criteria.andCategoryIdLike(categoryId + "%");
        }

        productInfoExample.setOrderByClause("ctime DESC");
        List<ProductInfo> rows = productInfoService.selectByExampleForOffsetPage(productInfoExample, offset, limit);

        List<Integer> productIds = rows.stream().map(ProductInfo::getId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(productIds)) {
            ProductDetailExample productDetailExample = new ProductDetailExample();
            ProductDetailExample.Criteria productDetailCriteria = productDetailExample.createCriteria();
            productDetailCriteria.andProductIdIn(productIds);

            List<ProductDetail> productDetails = productDetailService.selectByExample(productDetailExample);
            rows.forEach(p -> {
                productDetails.forEach(d -> {
                    if (d.getProductId().equals(p.getId())) {
                        if (StringUtils.isEmpty(d.getTitleEn())) {
                            p.setTitle("XXXXX");
                        } else {
                            p.setTitle(d.getTitleEn());
                        }
                    }
                });
            });
        }

        long total = productInfoService.countByExample(productInfoExample);
        Map<String, Object> result = new HashMap<>();
        result.put("list", rows);
        result.put("total", total);
        return new ProductResult(ProductResultConstant.SUCCESS, result);
    }

    @ApiOperation(value = "产品详情")
    @RequestMapping(value = "/info/{id}", method = RequestMethod.GET)
    @ResponseBody
    public Object info(@PathVariable("id") int id, HttpServletRequest request) {

        ProductInfo productInfo = productInfoService.selectByPrimaryKey(id);
        Integer userId = (Integer) request.getAttribute("currentUserId");
        Integer orgId = (Integer) request.getAttribute("currentOrgId");
        if (!productInfo.getCollectUserId().equals(userId)) {
            Subject subject = SecurityUtils.getSubject();
            String username = (String) subject.getPrincipal();
            JSONArray operableList = upmsApiService.getOperableListJson(username, orgId);

            boolean hasPermission = false;
            if (!CollectionUtils.isEmpty(operableList)) {
                for (Object o : operableList) {
                    JSONObject item = JSONObject.fromObject(o);
                    if (productInfo.getCollectUserId().equals(item.getInt("userId"))) {
                        hasPermission = true;
                        break;
                    }
                }
            }

            if (!hasPermission) {
                return new UpmsResult(UpmsResultConstant.INVALID_PERMISSION, null);
            }
        }

        ProductDetailExample productDetailExample = new ProductDetailExample();
        productDetailExample.createCriteria().andProductIdEqualTo(id);
        productDetailExample.setOrderByClause("id DESC");
        ProductDetail productDetail = productDetailService.selectFirstByExampleWithBLOBs(productDetailExample);
        JSONObject data = JSONObject.fromObject(ItvJsonUtil.writeValue(productInfo));
        data.putAll(JSONObject.fromObject(ItvJsonUtil.writeValue(productDetail)));

        return new ProductResult(ProductResultConstant.SUCCESS, data);
    }

    @ApiOperation(value = "批量修改产品分类和产品状态")
    @RequestMapping(value = "/update-batch", method = RequestMethod.POST)
    @ResponseBody
    public Object updateBatch(HttpServletRequest request) throws IOException {
        String requestStr = super.getInputStream(request);
        JSONObject data = JSONObject.fromObject(requestStr);
        String productIds = data.getString("ids");

        ProductInfo productInfo = new ProductInfo();
        ProductInfoExample productInfoExample = new ProductInfoExample();
        productInfoExample.createCriteria().andIdIn(Splitter.on(",").splitToList(productIds).stream().map(Integer::valueOf).collect(Collectors.toList()));
        // 更新分类
        if (!StringUtils.isEmpty(data.optString("categoryId"))) {
            productInfo.setCategoryId(data.optString("categoryId"));
            productInfo.setCategory(productCategoryService.getCategoryByIds(data.optString("categoryId")));
        }

        // 更新状态
        if (data.optInt("status", -1) != -1) {
            productInfo.setStatus((byte) data.optInt("status"));
        }

        productInfo.setReleaseTime(System.currentTimeMillis());
        int count = productInfoService.updateByExampleSelective(productInfo, productInfoExample);

        return new UpmsResult(UpmsResultConstant.SUCCESS, count);
    }

    @ApiOperation(value = "添加产品")
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    public Object create(HttpServletRequest request) throws IOException {

        Integer userId = (Integer) request.getAttribute("currentUserId");
        Integer orgId = (Integer) request.getAttribute("currentOrgId");

        String requestStr = super.getInputStream(request);
        JSONObject data = JSONObject.fromObject(requestStr);

        Integer id = productInfoService.createProduct(userId, orgId, data);
        return new UpmsResult(UpmsResultConstant.SUCCESS, id);
    }

    @ApiOperation(value = "修改产品")
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @ResponseBody
    public Object update(HttpServletRequest request) throws IOException {
        Integer orgId = (Integer) request.getAttribute("currentOrgId");
        String requestStr = super.getInputStream(request);
        JSONObject data = JSONObject.fromObject(requestStr);

        JSONObject info = new JSONObject();

        Integer productId = data.getInt("id");

        info.put("id", productId);
        info.put("title", data.opt("title"));
        info.put("mainPic", data.opt("mainPic"));
        info.put("category", data.opt("category"));
        info.put("categoryId", data.opt("categoryId"));
        info.put("sku", data.opt("sku"));
        info.put("costPrice", data.opt("costPrice"));
        info.put("costCurUnit", data.opt("costCurUnit"));
        info.put("salePrice", data.opt("salePrice"));
        info.put("saleCurUnit", data.opt("saleCurUnit"));
        info.put("sourceDomain", data.opt("sourceDomain"));
        info.put("sourceUrl", data.opt("sourceUrl"));
        info.put("productTag", data.opt("productTag"));
        info.put("status", data.opt("status"));

        data.put("id", null);
        data.put("title", null);
        data.put("mainPic", null);
        data.put("category", null);
        data.put("categoryId", null);
        data.put("sku", null);
        data.put("costPrice", null);
        data.put("costCurUnit", null);
        data.put("salePrice", null);
        data.put("saleCurUnit", null);
        data.put("sourceDomain", null);
        data.put("sourceUrl", null);
        data.put("productTag", null);
        data.put("status", null);

        // 单独处理更新状态/删除
        if (info.opt("status") != null) {
            ProductInfo productInfo = new ProductInfo();
            productInfo.setId(info.getInt("id"));
            productInfo.setStatus((byte) info.getInt("status"));

            productInfo.setReleaseTime(System.currentTimeMillis());
            int count = productInfoService.updateByPrimaryKeySelective(productInfo);
            return new UpmsResult(UpmsResultConstant.SUCCESS, count);
        }

        ProductInfo productInfo = ItvJsonUtil.readValue(info.toString(), ProductInfo.class);

        JSONArray variant = null;
        if (data.containsKey("variant")) {
            variant = data.getJSONArray("variant");
            data.put("variant", null);
        }

        JSONArray variantCompose = null;
        if (data.containsKey("variantCompose")) {
            variantCompose = data.getJSONArray("variantCompose");
            data.put("variantCompose", null);
        }

        ProductDetail productDetail = ItvJsonUtil.readValue(data.toString(), ProductDetail.class);
        ProductDetailExample productDetailExample = new ProductDetailExample();
        productDetailExample.createCriteria().andProductIdEqualTo(productId);

        if (productDetail.getTitleZh() != null) {
            productInfo.setTitle(productDetail.getTitleZh());
        }

        if (!CollectionUtils.isEmpty(variant)) {
            ProductInfo pInfo = productInfoService.selectByPrimaryKey(productId);
            JSONObject msgData = new JSONObject();
            msgData.put("orgId", orgId);
            msgData.put("userId", pInfo.getCollectUserId());
            msgData.put("variant", variant.toString());

            JmsUtil.sendMessage(jmsQueueTemplate, defaultQueueDestination, msgData.toString());
        }

        // 更新分类
        if (!StringUtils.isEmpty(productInfo.getCategoryId())) {
            productInfo.setCategory(productCategoryService.getCategoryByIds(productInfo.getCategoryId()));
        }

        productInfo.setReleaseTime(System.currentTimeMillis());
        int count = productInfoService.updateByPrimaryKeySelective(productInfo);

        if (variant != null) {
            productDetail.setVariant(variant.toString());
        }

        if (variantCompose != null) {
            productDetail.setVariantCompose(variantCompose.toString());
        }

        productDetailService.updateByExampleSelective(productDetail, productDetailExample);

        return new UpmsResult(UpmsResultConstant.SUCCESS, count);
    }

    @ApiOperation(value = "删除产品")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public Object delete(HttpServletRequest request) throws IOException {
        String requestStr = super.getInputStream(request);
        JSONObject data = JSONObject.fromObject(requestStr);

        Integer productId = data.getInt("id");

        ProductInfo productInfo = new ProductInfo();
        productInfo.setId(productId);
        productInfo.setStatus((byte) 5);

        int count = productInfoService.updateByPrimaryKeySelective(productInfo);
        return new UpmsResult(UpmsResultConstant.SUCCESS, count);
    }

    @ApiOperation(value = "产品采集")
    @RequestMapping(value = "/collect", method = RequestMethod.POST)
    @ResponseBody
    public Object collect(HttpServletRequest request) throws IOException {

        Integer userId = (Integer) request.getAttribute("currentUserId");
        Integer orgId = (Integer) request.getAttribute("currentOrgId");

        String requestStr = super.getInputStream(request);
        JSONObject data = JSONObject.fromObject(requestStr);

        Integer type = data.getInt("type");
        String sourceUrl = getSourceUrl(data);
        String category = data.optString("category");
        String categoryId = data.optString("categoryId");

        // 过滤掉不合理的采集地址
        try {
            URL url = new URL(sourceUrl);
            String host = url.getHost();// 获取主机名
            if (!(host.contains("detail.1688.com") || host.contains("detail.tmall.com") || host.contains("item.taobao.com"))) {
                return new ProductResult(ProductResultConstant.NOT_SUPPORT, sourceUrl);
            }
        } catch (Exception e) {
            return new ProductResult(ProductResultConstant.NOT_SUPPORT, sourceUrl);
        }

        Long startTime = System.currentTimeMillis();
        ProductCollectRecord collectRecord = new ProductCollectRecord();
        collectRecord.setUserId(userId);
        collectRecord.setType(type.byteValue());
        collectRecord.setUrl(sourceUrl);
        collectRecord.setStatus((byte) 0);
        collectRecord.setStartTime(startTime);
        productCollectRecordService.insertSelective(collectRecord);

        ProductCollectRecordExample example = new ProductCollectRecordExample();
        example.createCriteria().andUserIdEqualTo(userId).andStartTimeEqualTo(startTime);
        ProductCollectRecord record = productCollectRecordService.selectFirstByExample(example);


        // 发送消息
        data.put("recordId", record.getId());
        data.put("userId", userId);
        data.put("orgId", orgId);
        data.put("url", sourceUrl);

        // 放入redis
//        RedisUtil.zadd("product-collect-info", System.currentTimeMillis(), data.toString());

        JmsUtil.sendMessage(jmsQueueTemplate, defaultQueueDestination, data.toString());

        return new ProductResult(ProductResultConstant.SUCCESS, record.getId());
    }

    @ApiOperation(value = "产品采集")
    @RequestMapping(value = "/collect-local", method = RequestMethod.POST)
    @ResponseBody
    public Object collectByHtml(HttpServletRequest request) throws IOException {

        Integer userId = (Integer) request.getAttribute("currentUserId");
        Integer orgId = (Integer) request.getAttribute("currentOrgId");

        String requestStr = super.getInputStream(request);
        JSONObject data = JSONObject.fromObject(requestStr);

        Integer type = data.getInt("type");
        String sourceUrl = getSourceUrl(data);
        String category = data.optString("category");
        String categoryId = data.optString("categoryId");
        String content = data.getString("content");

        // 验证内容与url是否匹配
        try {
            Document document = Jsoup.parse(content);
//            Element linkElement = document.selectFirst("head > link:nth-child(35)");
            Element linkElement = document.getElementsByAttributeValue("rel", "canonical").first();

            String href = null;
            if (linkElement != null) {
                href = linkElement.attr("href");
            }
            if (sourceUrl.contains("detail.1688.com")) {
                if (href == null || !sourceUrl.contains(href)) {
                    return new ProductResult(ProductResultConstant.SOURCE_URL_NOT_MATCH, null);
                }
            } else if (sourceUrl.contains("item.taobao.com")) {
                if (href == null || !sourceUrl.equals(href.trim())) {
                    return new ProductResult(ProductResultConstant.SOURCE_URL_NOT_MATCH, null);
                }
            } else if (sourceUrl.contains("www.amazon")) {
                if (href == null || !href.contains("www.amazon")) {
                    return new ProductResult(ProductResultConstant.SOURCE_URL_NOT_MATCH, null);
                }
            }
            sourceUrl = href;

            // 校验是否已经被采集
            ProductInfoExample example = new ProductInfoExample();
            example.createCriteria().andOrgIdEqualTo(orgId).andSourceUrlEqualTo(sourceUrl);
            if (productInfoService.countByExample(example) > 0) {
                return new ProductResult(ProductResultConstant.SOURCE_URL_EXISTED, null);
            }
        } catch (Exception e) {
            return new ProductResult(ProductResultConstant.INVALID_PARAMETER, null);
        }

        // 过滤掉不合理的采集地址
        try {
            URL url = new URL(sourceUrl);
            String host = url.getHost();// 获取主机名
            if (!(host.contains("detail.1688.com") || host.contains("detail.tmall.com") || host.contains("item.taobao.com") || host.contains("www.amazon"))) {
                return new ProductResult(ProductResultConstant.NOT_SUPPORT, sourceUrl);
            }
        } catch (Exception e) {
            return new ProductResult(ProductResultConstant.NOT_SUPPORT, sourceUrl);
        }

        // 赋值修改后的sourceUrl
        data.put("url", sourceUrl);
        data.put("userId", userId);
        data.put("orgId", orgId);
        ProductCollectParamDTO paramDTO = ItvJsonUtil.readValue(data.toString(), ProductCollectParamDTO.class);
        if (paramDTO == null) {
            return new ProductResult(ProductResultConstant.FAILED, "Param error");
        }

        Long startTime = System.currentTimeMillis();
        ProductCollectRecord collectRecord = new ProductCollectRecord();
        collectRecord.setUserId(userId);
        collectRecord.setType(type.byteValue());
        collectRecord.setUrl(sourceUrl);
        collectRecord.setStatus((byte) 0);
        collectRecord.setStartTime(startTime);
        productCollectRecordService.insertSelective(collectRecord);


        paramDTO.setRecordId(collectRecord.getId());

        LOGGER.info("record Id" + paramDTO.getRecordId());

        CommonThreadPool.execute(() -> {
            productCollectService.collectProductByContent(paramDTO);
        });


        return new ProductResult(ProductResultConstant.SUCCESS, collectRecord.getId());
    }

    private String getSourceUrl(JSONObject data) {
        String sourceUrl = data.getString("url").trim();
        if (sourceUrl.contains("detail.1688.com") && sourceUrl.contains("?")) {
            sourceUrl = sourceUrl.trim().substring(0, data.getString("url").trim().indexOf("?"));
        } else if (sourceUrl.contains("item.taobao.com")) {
            Map<String, String> paramMap = new HashMap<String, String>();

            String url = sourceUrl;
            if (!"".equals(url)) {// 如果URL不是空字符串
                url = url.substring(url.indexOf('?') + 1);
                String paramaters[] = url.split("&");
                for (String param : paramaters) {
                    String values[] = param.split("=");
                    paramMap.put(values[0], values[1]);
                }
            }
            sourceUrl = sourceUrl.trim().substring(0, data.getString("url").trim().indexOf("?")) + "?id=" + paramMap.get("id");
        } else if (sourceUrl.contains("detail.tmall.com")) {
            Map<String, String> paramMap = new HashMap<String, String>();

            String url = sourceUrl;
            if (!"".equals(url)) {// 如果URL不是空字符串
                url = url.substring(url.indexOf('?') + 1);
                String paramaters[] = url.split("&");
                for (String param : paramaters) {
                    String values[] = param.split("=");
                    paramMap.put(values[0], values[1]);
                }
            }
            sourceUrl = sourceUrl.trim().substring(0, data.getString("url").trim().indexOf("?")) + "?id=" + paramMap.get("id");
        }
        return sourceUrl;
    }

    @ApiOperation(value = "产品导出")
    @RequestMapping(value = "/export-xxxxx", method = RequestMethod.POST)
    @ResponseBody
    public Object export(@RequestParam(value = "checkData") boolean checkData, HttpServletRequest request, HttpServletResponse response) throws IOException {
        Integer userId = (Integer) request.getAttribute("currentUserId");
        Integer orgId = (Integer) request.getAttribute("currentOrgId");

        String requestStr = super.getInputStream(request);
        JSONObject data = JSONObject.fromObject(requestStr);

        ProductInfoExample productInfoExample = new ProductInfoExample();
        ProductInfoExample.Criteria criteria = productInfoExample.createCriteria();

        criteria.andOrgIdEqualTo(orgId);

        String ids = data.optString("ids");
        if (!StringUtils.isEmpty(ids)) {
            criteria.andIdIn(Splitter.on(",").splitToList(ids).stream().map(Integer::valueOf).collect(Collectors.toList()));
        } else {

            // 状态
            String status = data.optString("status");
            if (!StringUtils.isEmpty(status)) {
                criteria.andStatusIn(Splitter.on(",").splitToList(status).stream().map(Byte::valueOf).collect(Collectors.toList()));
            }

            // 产品标记

            String productTags = data.optString("productTag");
            if (!StringUtils.isEmpty(productTags)) {
                criteria.andProductTagIn(Splitter.on(",").splitToList(productTags).stream().map(Byte::valueOf).collect(Collectors.toList()));
            }

            // 域名
            String sourceDomain = data.optString("sourceDomain");
            if (StringUtils.isNotBlank(sourceDomain)) {
                criteria.andSourceDomainEqualTo(sourceDomain);
            }

            // empUserId
            Integer empUserId = data.optInt("userId", 0);
            if (empUserId != 0) {
                criteria.andCollectUserIdEqualTo(empUserId);
            } else {
                criteria.andCollectUserIdEqualTo(userId);
            }

            // 开始时间和结束时间
            Long startTime = data.optLong("startTime", 0);
            Long endTime = data.optLong("endTime", 0);
            if (startTime != 0 && endTime != 0) {
                criteria.andReleaseTimeBetween(startTime, endTime);
            } else if (startTime != 0) {
                criteria.andReleaseTimeGreaterThanOrEqualTo(startTime);
            } else if (endTime != 0) {
                criteria.andReleaseTimeLessThanOrEqualTo(endTime);
            }

            String category = data.optString("categoryId");
            // 分类
            if (StringUtils.isNotBlank(category)) {
                criteria.andCategoryIdLike(category + "%");
            }

        }

        int count = productInfoService.countByExample(productInfoExample);

        if (checkData && count == 0) {
            return new ProductResult(ProductResultConstant.NOT_EXISTED, "当前条件未检索到任何数据");
        } else if (checkData && count >= 100) {
            return new ProductResult(ProductResultConstant.OVER_LIMIT_DATA, "请求数据量太大，请重新输入筛选条件");
        } else if (checkData) {
            return new ProductResult(ProductResultConstant.SUCCESS, count);
        }

        String country = data.getString("country");
        String brandName = data.optString("brandName");
        String manufacturer = data.optString("manufacturer");
//        String templateName = data.getString("templateName");
        String feed = data.optString("feed");
        String nodes1 = data.optString("nodes1");
        String nodes2 = data.optString("nodes2");
        String keyWord = data.optString("keyWord");

        ProductExportParamDTO paramDTO = new ProductExportParamDTO();
        paramDTO.setBrandName(brandName);
        paramDTO.setManufacturer(manufacturer);
        paramDTO.setCountry(country);
        paramDTO.setFeed(feed);
        paramDTO.setNodes1(nodes1);
        paramDTO.setNodes2(nodes2);
        paramDTO.setUpcNode1(data.optString("upcNode1"));
        paramDTO.setUpcNode2(data.optString("upcNode2"));
        paramDTO.setKeyWord(keyWord);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

        String filename = country + "_" + userId + "_" + formatter.format(LocalDateTime.now()) + ".xlsx";

        // 创建Excel文档
        // excel文档对象
        String wbTmp = productInfoService.exportProduct(productInfoExample, paramDTO);

        if (StringUtils.isEmpty(wbTmp)) {
            LOGGER.error("template File not existed");
            return new ProductResult(ProductResultConstant.FAILED, "failed");
        }

        File file = new File(wbTmp);
        if (!file.exists()) {
            LOGGER.error("template File not existed" + file.getAbsolutePath());
            return new ProductResult(ProductResultConstant.FAILED, "failed");
        }

        Workbook wb = null;
        try {
            wb = PoiUtils.createworkbook(new FileInputStream(file));
        } catch (InvalidFormatException e) {
            LOGGER.error("exception");
            return new ProductResult(ProductResultConstant.FAILED, "failed");
        }

        if (wb != null) {
            // 输出Excel文件
            PoiUtils.sendExcel(wb, filename, request, response);
            file.delete();
        }

        return new ProductResult(ProductResultConstant.SUCCESS, count);
    }

    @ApiOperation(value = "产品导出")
    @RequestMapping(value = "/export", method = RequestMethod.POST)
    @ResponseBody
    public Object exportPlus(@RequestParam(value = "checkData") boolean checkData, HttpServletRequest request, HttpServletResponse response) throws IOException {
        Integer userId = (Integer) request.getAttribute("currentUserId");
        Integer orgId = (Integer) request.getAttribute("currentOrgId");

        String requestStr = super.getInputStream(request);
        JSONObject data = JSONObject.fromObject(requestStr);

        ProductInfoExample productInfoExample = new ProductInfoExample();
        ProductInfoExample.Criteria criteria = productInfoExample.createCriteria();

        criteria.andOrgIdEqualTo(orgId);

        String ids = data.optString("ids");
        if (!StringUtils.isEmpty(ids)) {
            criteria.andIdIn(Splitter.on(",").splitToList(ids).stream().map(Integer::valueOf).collect(Collectors.toList()));
        } else {

            // 状态
            String status = data.optString("status");
            if (!StringUtils.isEmpty(status)) {
                criteria.andStatusIn(Splitter.on(",").splitToList(status).stream().map(Byte::valueOf).collect(Collectors.toList()));
            }

            // 产品标记

            String productTags = data.optString("productTag");
            if (!StringUtils.isEmpty(productTags)) {
                criteria.andProductTagIn(Splitter.on(",").splitToList(productTags).stream().map(Byte::valueOf).collect(Collectors.toList()));
            }

            // 域名
            String sourceDomain = data.optString("sourceDomain");
            if (StringUtils.isNotBlank(sourceDomain)) {
                criteria.andSourceDomainEqualTo(sourceDomain);
            }

            // empUserId
            Integer empUserId = data.optInt("userId", 0);
            if (empUserId != 0) {
                criteria.andCollectUserIdEqualTo(empUserId);
            } else {
                criteria.andCollectUserIdEqualTo(userId);
            }

            // 开始时间和结束时间
            Long startTime = data.optLong("startTime", 0);
            Long endTime = data.optLong("endTime", 0);
            if (startTime != 0 && endTime != 0) {
                criteria.andReleaseTimeBetween(startTime, endTime);
            } else if (startTime != 0) {
                criteria.andReleaseTimeGreaterThanOrEqualTo(startTime);
            } else if (endTime != 0) {
                criteria.andReleaseTimeLessThanOrEqualTo(endTime);
            }

            String category = data.optString("categoryId");
            // 分类
            if (StringUtils.isNotBlank(category)) {
                criteria.andCategoryIdLike(category + "%");
            }

        }

        int count = productInfoService.countByExample(productInfoExample);

        if (checkData) {
            return new ProductResult(ProductResultConstant.SUCCESS, count);
        }

        String country = data.getString("country");
        String brandName = data.optString("brandName");
        String manufacturer = data.optString("manufacturer");
//        String templateName = data.getString("templateName");
        String feed = data.optString("feed");
        String nodes1 = data.optString("nodes1");
        String nodes2 = data.optString("nodes2");
        String keyWord = data.optString("keyWord");

        ProductExportParamDTO paramDTO = new ProductExportParamDTO();
        paramDTO.setBrandName(brandName);
        paramDTO.setManufacturer(manufacturer);
        paramDTO.setCountry(country);
        paramDTO.setFeed(feed);
        paramDTO.setNodes1(nodes1);
        paramDTO.setNodes2(nodes2);
        paramDTO.setUpcNode1(data.optString("upcNode1"));
        paramDTO.setUpcNode2(data.optString("upcNode2"));
        paramDTO.setKeyWord(keyWord);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

        String filename = country + "_" + userId + "_" + formatter.format(LocalDateTime.now()) + ".xlsx";

        // 创建Excel文档
        // excel文档对象
        XSSFWorkbook wb = new XSSFWorkbook();
        // 数据
        List<ProductExportResultDTO> exportProductList = productInfoService.getExportProductList(productInfoExample, paramDTO);
        File templateFile;
        try {

            templateFile = new File(AMAZON_TEMPLATE_BASE_PATH + "template.xlsx");

            if (!templateFile.exists()) {
                LOGGER.info("template File not existed" + templateFile.getAbsolutePath());
                return new ProductResult(ProductResultConstant.FAILED, "failed");
            }
        } catch (Exception e) {
            LOGGER.info("template File not existed");
            return new ProductResult(ProductResultConstant.FAILED, "failed");
        }

        try {
            handleWorkBookData(wb, exportProductList, templateFile);
        } catch (Exception e) {
            LOGGER.error("导出失败", e);
            return new ProductResult(ProductResultConstant.FAILED, "failed");
        }

        // 输出Excel文件
        PoiUtils.sendExcel(wb, filename, request, response);

        return new ProductResult(ProductResultConstant.SUCCESS, count);
    }

    private void handleWorkBookData(XSSFWorkbook wb, List<ProductExportResultDTO> exportProductList, File templateFile) throws IOException {
        XSSFWorkbook tempWb = new XSSFWorkbook(new FileInputStream(templateFile));

        XSSFSheet tempSheet = tempWb.getSheetAt(0);
        Row row3 = tempSheet.getRow(0);

        XSSFSheet sheet = wb.createSheet();
        int rowIndex = 0;
        Row row1 = sheet.createRow(rowIndex++);

        List<String> fields = new ArrayList<>();
        int index = 0;
        for (Cell cell : row3) {
            //设置单元格类型
            cell.setCellType(CellType.STRING);

            Cell cellTarget = row1.createCell(index++);
            cellTarget.setCellType(CellType.STRING);
            if (StringUtils.isNotEmpty(cell.getStringCellValue())) {
                fields.add(cell.getStringCellValue());
                cellTarget.setCellValue(cell.getStringCellValue());
            }
        }

        for (ProductExportResultDTO resultDTO : exportProductList) {

            Row rowNew = sheet.createRow(rowIndex++);

            Cell cell = null;
            int fieldIndex = 0;
            for (String field : fields) {
                cell = rowNew.createCell(fieldIndex++);// 序号
                cell.setCellType(CellType.STRING);// 文本类型

                String fieldTrim = field.trim();

                switch (fieldTrim) {
                    case "item_sku":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getItemSku()).orElse(""));
                        break;
                    case "item_name":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getItemName()).orElse(""));
                        break;
                    case "external_product_id":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getExternalProductId()).orElse(""));
                        break;
                    case "external_product_id_type":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getExternalProductIdType()).orElse(""));
                        break;
                    // 产品分类
                    case "feed_product_type":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getFeedProductType()).orElse(""));
                        break;
                    case "brand_name":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getBrandName()).orElse(""));
                        break;
                    case "manufacture":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getManufacture()).orElse(""));
                        break;
                    case "part_number":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getPartNumber()).orElse(""));
                        break;
                    case "product_description":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getProductDescription()).orElse(""));
                        break;
                    case "update_delete":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getUpdateDelete()).orElse(""));
                        break;
                    case "sale_price":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getSalePrice()).orElse(""));
                        break;
                    case "currency":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getCurrency()).orElse(""));
                        break;
                    case "condition_type":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getConditionType()).orElse(""));
                        break;
                    case "condition_note":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getConditionNote()).orElse(""));
                        break;
                    case "quantity":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getQuantity()).orElse(""));
                        break;
                    case "website_shipping_weight":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getWebsiteShippingWeight()).orElse(""));
                        break;
                    case "website_shipping_weight_unit_of_measure":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getWebsiteShippingWeightUnitOfMeasure()).orElse(""));
                        break;
                    // 简要描述
                    case "bullet_point1":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getBulletPoint1()).orElse(""));
                        break;
                    case "bullet_point2":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getBulletPoint2()).orElse(""));
                        break;
                    case "bullet_point3":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getBulletPoint3()).orElse(""));
                        break;
                    case "bullet_point4":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getBulletPoint4()).orElse(""));
                        break;
                    case "bullet_point5":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getBulletPoint5()).orElse(""));
                        break;
                    // 小分类
                    case "recommended_browse_nodes1":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getRecommendedBrowseNodes1()).orElse(""));
                        break;
                    case "recommended_browse_nodes2":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getRecommendedBrowseNodes2()).orElse(""));
                        break;
                    // 关键字
                    case "generic_keywords1":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getGenericKeywords1()).orElse(""));
                        break;
                    case "generic_keywords2":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getGenericKeywords2()).orElse(""));
                        break;
                    case "generic_keywords3":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getGenericKeywords3()).orElse(""));
                        break;
                    case "generic_keywords4":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getGenericKeywords4()).orElse(""));
                        break;
                    case "generic_keywords5":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getGenericKeywords5()).orElse(""));
                        break;

                    // 图片
                    case "main_image_url":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getMainImageUrl()).orElse(""));
                        break;
                    case "other_image_url1":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getOtherImageUrl1()).orElse(""));
                        break;
                    case "other_image_url2":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getOtherImageUrl2()).orElse(""));
                        break;
                    case "other_image_url3":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getOtherImageUrl3()).orElse(""));
                        break;
                    case "other_image_url4":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getOtherImageUrl4()).orElse(""));
                        break;
                    case "other_image_url5":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getOtherImageUrl5()).orElse(""));
                        break;
                    case "other_image_url6":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getOtherImageUrl6()).orElse(""));
                        break;
                    case "other_image_url7":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getOtherImageUrl7()).orElse(""));
                        break;
                    case "other_image_url8":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getOtherImageUrl8()).orElse(""));
                        break;
                    // 暂时未用到
                    case "is_separate":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getIsSeparate()).orElse(""));
                        break;

                    // 主副关系（主产品是Parent） 副产品是：Child
                    case "parent_child":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getParentChild()).orElse(""));
                        break;
                    // 这个地方只需要主产品的SKU，，只需要副产品填写
                    case "parent_sku":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getParentSku()).orElse(""));
                        break;
                    // 这个地方也只有副产品有这个词
                    case "relationship_type":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getRelationshipType()).orElse(""));
                        break;
                    // 这里是颜色颜色和尺寸的变化主体
                    case "variation_theme":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getVariationTheme()).orElse(""));
                        break;
                    case "color_name":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getColorName()).orElse(""));
                        break;
                    case "color_map":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getColorMap()).orElse(""));
                        break;
                    case "size_name":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getSizeName()).orElse(""));
                        break;
                    case "size_map":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getSizeMap()).orElse(""));
                        break;
                    case "standard_price":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getStandardPrice()).orElse(""));
                        break;
                    case "sale_from_date":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getSaleFromDate()).orElse(""));
                        break;
                    case "sale_end_date":
                        cell.setCellValue(Optional.ofNullable(resultDTO.getSaleEndDate()).orElse(""));
                        break;
                    default:
                }
            }
        }
    }
}